package pl.edu.agh.broker.mns.server.internal;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.SocketException;
import java.rmi.Remote;

public class SingleReferenceServer implements StartStopListener {

	private class SocketListeningThread extends Thread {

		private ServerSocket socket;
		private boolean running;

		public SocketListeningThread(int port) throws IOException {
			socket = new ServerSocket(port);
			this.running = true;
		}

		@Override
		public void run() {
			while (running) {
				try {
					ObjectOutputStream os = new ObjectOutputStream(socket
							.accept().getOutputStream());
					synchronized (SingleReferenceServer.this) {
						os.writeObject(reference);
						os.close();
					}
				} catch (IOException e) {
					if (e instanceof SocketException) {
						continue;
					} else {
						throw new RuntimeException(e);
					}
				}
			}
		}

		public void end() throws IOException {
			running = false;
			socket.close();
		}
	}

	private final int port;
	private SocketListeningThread listeningThread;
	private Remote reference;

	public SingleReferenceServer(int port) {
		this.port = port;
	}

	@Override
	public void onStart() {
		try {
			listeningThread = new SocketListeningThread(port);
			listeningThread.start();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void onStop() {
		synchronized (this) {
			try {
				listeningThread.end();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public void setReference(Remote reference) {
		this.reference = reference;
	}

}
